/**
 * @author Kristian Mandrup
 * @date June 10, 2009
 * @version 0.1
 * 
 * Utility functions used by ChildrenParser
 */

/**
 * Use childSelector to find children
 * @param {Object} jsonObj
 * @param {Object} childSelector
 */
m3gen.ChildrenParser.prototype.findChildrenBySelector = function(childSelector) {
	var childrenFound = [];
	var jsonObj = this.getActiveObj();
	if (this.isFunction(childSelector)) {
		childrenFound = childSelector(jsonObj);
	}
	else {		
		childrenFound = this.resolveObjWithSelector(jsonObj, childSelector)
	}
	if (this.isValidObj(childrenFound) && this.isNotEmptyArray(childrenFound)) {
		return this.flatten(childrenFound);
	} else {
		return [];
	}		
}

 /**
 * Resolve single object in the instance model
 * @param {Object} childrenFound
 */
m3gen.ChildrenParser.prototype.resolveObjects = function(childrenFound, options) {
	var resolveArray = function(childrenFound, options) {
		if (that.isNotEmptyArray(childrenFound)) {
			// Resolve each object in array referenced by childrenFound
			return that.resolveArrayObj(childrenFound, options);
		}
		else {
			return [];
		}
	}
	var that = this;
		
	// start with empty array
	var branchChildren = [];
    if (this.isArray(childrenFound)) {
		branchChildren = resolveArray(childrenFound, options);
    } else {
		// Resolve single object referenced by childrenFound
		branchChildren = this.resolveSimpleObj(foundObj, options);
	}
	return branchChildren;
}


/**
 * Resolve a simple object (not an array)
 * @param {Object} obj
 * 
 * Returns the populated branchChildren
 */
m3gen.ChildrenParser.method('resolveSimpleObj', function(obj, options) {
	var resolvedObj = obj;
	var found = true;
	var simpleNode = {};
	// TODO: Resolve in context of rootItem ?
	if (obj['$ref']) {
		var jsonRef = obj['$ref'];
		// resolve root
		if (this.triedToResolveJson) {
			this.handle(m3gen.msg.ResolveJsonModelError);
		}
		else {
			resolveJsonModel();
			this.triedToResolveJson = true;														
		}					
		resolvedObj = obj;					
	} else if (obj['_loadObject'] === 'undefined') {
		found = false;							
	} 
	if (found && resolvedObj) {
		// Get the JsonObjParser constructor and initialize it
		var node = this.getJsonObjParserInstance().execute(resolvedObj, options);
		if (this.isValidObj(node)) {
			simpleNode = node;
		}
	} else {
		// console.log('No object was found for selector');
	}
	
	return simpleNode;
});

/**
 * 
 * @param {Object} arrayObj
 */
m3gen.ChildrenParser.method('resolveArrayObj', function(arrayObj, options) {
	var branchChildren = [];
	var that = this;
	if (this.isNotEmptyArray(arrayObj)) {
		arrayObj.forEach(function(obj){
			if (that.isArray(obj)) {
				var nodes = that.resolveArrayObj(obj);
				nodes = that.flatten(nodes)
				if (that.isNotEmptyArray(nodes)) {
					that.concatArrays(branchChildren, nodes);
				}
			}
			else {
				var node = that.resolveSimpleObj(obj, options);
				if (that.isValidObj(node)) {
					branchChildren.push(node);
				}
			}
		});
	}
	return branchChildren;						
});
